package edu.bmstu.rslab;

import java.awt.geom.Point2D;

/**
 * Created by Chikh (using IntelliJ IDEA).
 * Date: 05.03.2009
 * Time: 13:21:42
 */
public class Translator {

    public void setBasis(BasisOfLCS csBasis) {
        this.csBasis = csBasis;
    }

    public Point2D translate(Point2D pImageCS) {
        Point2D pBase = csBasis.getPBase();

        Point2D lOX = getIntersection(csBasis.getPO(), csBasis.getPX());
        Point2D lYB = getIntersection(csBasis.getPY(), pBase);
        Point2D plOXlYB = getIntersection(lOX, lYB);
        Point2D lOY = getIntersection(csBasis.getPO(), csBasis.getPY());
        Point2D lXB = getIntersection(csBasis.getPX(), pBase);
        Point2D plOYlXB = getIntersection(lOY, lXB);
        Point2D lHorizon = getIntersection(plOXlYB, plOYlXB);
        Point2D lBase = new Point2D.Double(lHorizon.getX()/(lHorizon.getX()*pBase.getX() + lHorizon.getY()*pBase.getY()),
                lHorizon.getY()/(lHorizon.getX()*pBase.getX()+lHorizon.getY()*pBase.getY()));
        Point2D lProjectingX = getIntersection(plOYlXB, pImageCS);
        Point2D lProjectingY = getIntersection(plOXlYB, pImageCS);
        Point2D pX = getIntersection(lBase, lProjectingX);
        Point2D pY = getIntersection(lBase, lProjectingY);
        Point2D pBaseX = getIntersection(lOY, lBase);
        Point2D pBaseY = getIntersection(lOX, lBase);

        double lengthBaseX = pBase.distance(pBaseX);
        double lengthBaseY = pBase.distance(pBaseY);
        double lengthX = pBaseX.distance(pX);
        double lengthY = pBaseY.distance(pY);

        double X = lengthX/lengthBaseX;
        double Y = lengthY/lengthBaseY;

        return new Point2D.Double(X, Y);
    }

    public Point2D inverseTranslate(Point2D pointLCS) {

        Point2D pBase = csBasis.getPBase();
        Point2D lOX = getIntersection(csBasis.getPO(), csBasis.getPX());
        Point2D lYB = getIntersection(csBasis.getPY(), pBase);
        Point2D plOXlYB = getIntersection(lOX, lYB);
        Point2D lOY = getIntersection(csBasis.getPO(), csBasis.getPY());
        Point2D lXB = getIntersection(csBasis.getPX(), pBase);
        Point2D plOYlXB = getIntersection(lOY, lXB);
        Point2D lHorizon = getIntersection(plOXlYB, plOYlXB);
        Point2D lBase = new Point2D.Double(lHorizon.getX()/(lHorizon.getX()*pBase.getX() + lHorizon.getY()*
                pBase.getY()), lHorizon.getY()/(lHorizon.getX()*pBase.getX()+lHorizon.getY()*pBase.getY()));
        Point2D pBaseX = getIntersection(lOY, lBase);
        Point2D pBaseY = getIntersection(lOX, lBase);
        Point2D pX = new Point2D.Double((pBase.getX()-pBaseX.getX())*pointLCS.getX()+pBaseX.getX(),
                (pBase.getY()-pBaseX.getY())*pointLCS.getX()+pBaseX.getY());
        Point2D pY = new Point2D.Double((pBase.getX()-pBaseY.getX())*pointLCS.getY()+pBaseY.getX(),
                (pBase.getY()-pBaseY.getY())*pointLCS.getY()+pBaseY.getY());
        Point2D lProjectingX = getIntersection(pX, plOYlXB);
        Point2D lProjectingY = getIntersection(pY, plOXlYB);

        return getIntersection(lProjectingX, lProjectingY);
    }

    private Point2D getIntersection(Point2D p1, Point2D p2) {
        return new Point2D.Double((p2.getY()-p1.getY())/(p1.getX()*p2.getY()-p2.getX()*p1.getY()),
                (p1.getX()-p2.getX())/(p1.getX()*p2.getY()-p2.getX()*p1.getY()));
    }

    private BasisOfLCS csBasis;
}